package com.hmy.finance.service.core.dto;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.hmy.finance.bo.request.ReceivablesBaseDetailQueryRequest;
import com.hmy.finance.common.enums.BusinessBillTypeEnum;
import com.hmy.finance.common.properties.ReceivableInventoryOverdueRule;
import com.hmy.finance.dal.po.ContractDailyBillPo;
import com.hmy.finance.dal.po.DeviceDailyBillPo;
import com.hmy.finance.dal.po.DeviceRentalRecordPo;
import com.hmy.finance.dal.po.ProfitLossRecordPo;
import com.hmy.finance.dal.po.json.ContractExtensionInfoJson;
import com.hmy.finance.dal.po.json.CustomerExtensionInfoJson;
import com.hmy.finance.dal.po.json.OrderExtensionInfoJson;
import lombok.Data;

import java.io.Serializable;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 每日流水处理任务数据传输对象
 *
 * @author songkf
 */
@Data
public class DailyInvoiceGenerationJobDto implements Serializable {

    private static final long serialVersionUID = 6777571242948648872L;
    /**
     * 开始日期
     */
    private LocalDate startDate;
    /**
     * 结束日期
     */
    private LocalDate endDate;
    /**
     * 循环次数
     */
    private int loop = 1;
    /**
     * 处理日期
     */
    private LocalDate handleDate;
    /**
     * 销售合同信息
     */
    private ContractExtensionInfoJson contractExtensionInfoJson;
    /**
     * 客户信息
     */
    private CustomerExtensionInfoJson customerExtensionInfoJson;
    /**
     * 订单信息
     */
    private OrderExtensionInfoJson orderExtensionInfoJson;
    /**
     * 设备租赁记录集合
     */
    private List<DeviceRentalRecordPo> deviceRentalRecordList;
    /**
     * 设备日费用流水集合
     */
    private List<DeviceDailyBillPo> deviceDailyBillList;
    /**
     * 合同日费用流水
     */
    private ContractDailyBillPo contractDailyBillPo;
    /**
     * 账期区间
     */
    private Map<String, PeriodInterval> accountPeriodIntervalMap = new HashMap<>();
    /**
     * 逾期规则
     */
    private ReceivableInventoryOverdueRule overdueRule;
    /**
     * 计算合同应收盘点的设备日流水数据
     */
    private List<DeviceDailyBillPo> calculateContractReceivableInventoryDeviceDailyBillList;


    /**
     * 通过ContractExtensionInfoJson构建DailyInvoiceGenerationJobDto
     *
     * @author songkf
     */
    public static DailyInvoiceGenerationJobDto buildDailyInvoiceGenerationJobDto(ContractExtensionInfoJson contractExtensionInfoJson, ReceivableInventoryOverdueRule overdueRule, LocalDate startDate, LocalDate endDate) {
        DailyInvoiceGenerationJobDto dailyInvoiceGenerationJobDto = new DailyInvoiceGenerationJobDto();
        dailyInvoiceGenerationJobDto.setContractExtensionInfoJson(contractExtensionInfoJson);
        dailyInvoiceGenerationJobDto.setOverdueRule(overdueRule);
        dailyInvoiceGenerationJobDto.setStartDate(startDate);
        dailyInvoiceGenerationJobDto.setEndDate(endDate);
        if (Objects.nonNull(startDate) && Objects.nonNull(endDate)) {
            dailyInvoiceGenerationJobDto.setLoop((int) (endDate.toEpochDay() - startDate.toEpochDay() + 1));
        }
        return dailyInvoiceGenerationJobDto;
    }

    public void setOrderExtensionInfoJson(OrderExtensionInfoJson orderExtensionInfoJson) {
        this.orderExtensionInfoJson = orderExtensionInfoJson;
    }

    public ReceivablesBaseDetailQueryRequest getReceivablesBaseDetailQueryRequest() {
        return new ReceivablesBaseDetailQueryRequest(contractExtensionInfoJson.getContractId());
    }

    public void setCalculateContractReceivableInventoryDeviceDailyBillList(List<DeviceDailyBillPo> calculateContractReceivableInventoryDeviceDailyBillList) {
        this.calculateContractReceivableInventoryDeviceDailyBillList = calculateContractReceivableInventoryDeviceDailyBillList;
    }

    public Wrapper<ProfitLossRecordPo> getReceivableAdjustProfitLossRecordQueryWrapper() {
        return Wrappers.<ProfitLossRecordPo>lambdaQuery().eq(ProfitLossRecordPo::getContractId, contractExtensionInfoJson.getContractId())
                .eq(ProfitLossRecordPo::getBusinessBillType, BusinessBillTypeEnum.RECEIVABLE_ADJUSTMENT)
                .ge(ProfitLossRecordPo::getFeeIncurredTime, handleDate.atStartOfDay())
                .le(ProfitLossRecordPo::getFeeIncurredTime, handleDate.atTime(LocalTime.MAX));
    }

    /**
     * 账期区间
     *
     * @author songkf
     */
    @Data
    public static class PeriodInterval {
        private ReceivableInventoryOverdueRule.Rule overdueRule;
        /**
         * 账期开始时间
         */
        private LocalDate start;
        /**
         * 账期结束时间
         */
        private LocalDate end;
        /**
         * 金额
         */
        private BigDecimal amount = BigDecimal.ZERO;

        public PeriodInterval(LocalDate start, LocalDate end, ReceivableInventoryOverdueRule.Rule overdueRule) {
            this.start = start;
            this.end = end;
            this.overdueRule = overdueRule;
        }
    }
}
